home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / program / cprog.EXE / C5.TXT < prev    next >
Text File  |  1996-07-05  |  18KB  |  442 lines

  1. C dili - 5. Konu
  2.  
  3.  
  4. Fonksiyonlar ve degiskenler
  5.  
  6. KARETOPL.C:
  7. ================================================================
  8.  
  9. int toplam; /* Global degisken      */
  10.  
  11. main()
  12. {
  13. int index;
  14.  
  15.    baslik();        /* Baslik isimli fonksiyonu cagirir     */
  16.  
  17.    for (index = 1;index <= 7;index++)
  18.      kare(index); /* Bu, kare fonksiyonunu cagirir.  */
  19.  
  20.    bitis();        /* Bu da, bitis isimli fonksiyonu cagirir */
  21. }
  22.  
  23. baslik()        /* Bu fonksiyonun tanimidir                 */
  24. {
  25.    toplam = 0;     /* "Toplam" isimli degiskene 0 degeri atanir.. */
  26.    printf("Bu, kare programinin basligidir\n\n");
  27. }
  28.  
  29. kare(rakam)   /* Bu, kare fonksiyonunun baslangicidir */
  30. int rakam;
  31. {
  32. int karesi;                /* Yerel degisken tanimlaniyor */
  33.  
  34.    karesi = rakam * rakam ;  /* Karesini olusturuyor. */
  35.    toplam += karesi;        /* Bulunan deger, toplama ekleniyor */
  36.    printf("%d nin karesi %d dir.\n",rakam,karesi);
  37. }
  38.  
  39. bitis()   /* Bitis fonksiyonu tanimlaniyor.  */
  40. {
  41.    printf("\nKarelerin toplami: %d dir..\n",toplam);
  42. }
  43. ================================================================
  44.  
  45.  
  46. KARETOPL.C isimli programa bir bakin. Bu program, fonksiyonlu ilk
  47. programimiz. Goreceginiz gibi C de fonksiyon tanimlamak o kadar kolaydir
  48. ki, programlarin fonksiyonlara parcalanmasi neredeyse istemeden olur.
  49. Aslinda, biz fonksiyonlari kullanip duruyorduk, ornegin kullandigimiz
  50. printf komutu, bir fonksiyondur. Printf fonksiyonu, derleyici ile gelen
  51. fonksiyon kutuphanesinin bir parcasidir.
  52.  
  53. Bu programin calisan kismina bir bakin. baslik() isimli bir satir ile
  54. basliyor. Iste C de, herhangi bir fonksiyon, bu sekilde cagirilir: ismi,
  55. parantez, ve sayet varsa bu fonksiyona gonderilmesi istenen degerler
  56. yazilir. Programin calismasi bu satira gelince, baslik isimli fonksiyona
  57. atlanir, ve buradaki islemler yapilir. Bitince, program geri doner, ve
  58. ana programda kaldigi yerden isleme devam eder, ve "for" dongusune gelir.
  59. Burada, yedi kere "kare" isimli bir fonksiyonu cagirir, daha sonra "bitis"
  60. fonksiyonunu cagirir ve program sona erer. 
  61.  
  62. FONKSIYONUN TANIMLANMASI
  63.  
  64. main'den sonra ayni main'in ozelliklerini tasayan bir program
  65. goreceksiniz. Sadece bunun ismi "baslik()" olarak tanimlanmistir. Bu
  66. basligin ilk satirinda "toplam" degiskeninin degeri 0 a atanir, ve bir
  67. baslik satiri yazilir. Dikkat ederseniz, "toplam" degiskenini,
  68. fonksiyonlarin disinda, programin basinda tanimlamistik. Bu sekilde
  69. tanimlanan bir degisken, o programdaki herhangi bir fonksiyondan
  70. cagirilabilir.  Bu tip degiskenlere "global" denir. 
  71.  
  72. Bu iki satiri main() in icine de koymamiz mumkundur. Bu ornek sadece
  73. fonksiyonlarin kullanimini gostermektedir. 
  74.  
  75. FONKSIYONA DEGER GECIRMEK
  76.  
  77. Ana programda, "for" dongusunde, "index++" deyimini goruyorsunuz. Ilk
  78. olarak gecen konuda ogrendigimiz birer birer arttirma metoduna alismaya
  79. bakin, cunku C programlarinda cok karsilasacaksiniz.
  80.  
  81. "kare" isimli fonksiyonu cagirirken, bir yenilik kattik. Yani, parantez
  82. icindeki "index" deyimini. Bu da derleyiciye, o fonksiyona gidince,
  83. "index" in o andaki degerini de beraberimizde goturmek istedigimizi
  84. belirtir. "Kare" isimli fonksiyonun basligina baktigimizda ise,
  85. parantezler icinde bir baska degisken ismi goruyoruz: "rakam." Ana
  86. programdan "kare(index)" dedigimizde gelen index'in degerine, bu fonksiyon
  87. icinde 'rakam' diyecegimizi belirtiyoruz. Buna rakam demek yerine
  88. istedigimiz herhangi bir ismi verebilirdik - C nin degisken isim
  89. kurallarina uymasi sarti ile. Fonksiyon, ona ne tip bir deger
  90. gecirilecegini bilmesi icinde, hemen alt satirda, "int rakam" diyerek,
  91. gelecek bu degerin bir integer olacagini belirtiyoruz. 
  92.  
  93. Kume isaretinden sonra, "int karesi" deyimi ile, sadece bu fonksiyonun
  94. icinde tanimli olan bir degisken daha tanimlandigini goruyoruz.  Bundan
  95. sonra, "karesi" degiskenine 'rakam' in karesini atiyoruz, ve "toplam"
  96. degiskenine de "karesi" degiskeninin degerini ekliyoruz.
  97.  
  98. BIR FONKSIYONA DEGER ATAMA HAKKINDA DAHA BILGI
  99.  
  100. Aslinda "index" in degerini fonksiyona gecirdigimizde, anlattigimdan biraz
  101. daha fazla sey oldu. Gercekte, "index" in degerini gecirmedik bu
  102. fonksiyona, o degerin bir kopyasini gecirdik. Bu sayede, "index" in asil
  103. degeri, fonksiyon tarafindan kazara zarar goremez. "rakam" isimli
  104. degiskenimizi fonksiyon icinde istedigimiz gibi degistirebilirdik, fakat
  105. ana programa geri dondugumuzde, "index" in degeri yine ayni kalirdi. 
  106.  
  107. Boylece, degiskenin degerinin zarar gormesini onlemis oluyoruz, fakat ayni
  108. zamanda, ana programa bir deger dondurmemize de mani oluyoruz. Pointers
  109. kisimina gelince, cagiran fonkisyona degeri dondurmek icin, iyi tanimli
  110. bir metod gorecegiz. O zamana kadar ana programa deger dondurmenin yegane
  111. yolu, global degiskenler kullanaraktir. Global degiskenlerden biraz
  112. bahsetmistik, bu konu icersinde, daha da bahsedecegiz. 
  113.  
  114. Programa devam ederek, bitis() isimli bir fonksiyonun cagirilisina
  115. geliyoruz. Bu cagirma da, hicbir yerel degiskeni olmayan fonksiyonu
  116. cagirir. "toplam" degiskeninin degerini yazdiktan sonra ana kesime donen
  117. program, yapacak baska birsey olmadigini gorunce durur. 
  118.  
  119. UFAK BIR YALANI ITIRAF ETME ZAMANI
  120.  
  121. Biraz once size bir fonksiyondan bir deger dondurmek icin yegane yolun
  122. global degiskenler ile olabilecegini soylemistim. Fakat bir baska metod
  123. daha var. Lutfen KARELER.C isimli programa bakin...
  124.  
  125. KARELER.C:
  126. =====================================================================
  127.  
  128. main()  /* Ana program burada.  */
  129. {
  130. int x,y;
  131.  
  132.    for(x = 0;x <= 7;x++) {
  133.       y = squ(x);              /* x*x i hesaplayalim.. */
  134.       printf("%d nin karesi %d dir...\n",x,y);
  135.    }
  136.  
  137.    for (x = 0;x <= 7;++x) 
  138.       printf("%d nin karesi %d dir...\n",x,squ(x));
  139. }
  140.  
  141. squ(in)  /* Bir rakamin karesini bulan fonksiyon */
  142. int in;
  143. {
  144. int kare;
  145.  
  146.    kare = in * in;
  147.    return(kare);      /* Yeni buldugumuz deger donduruluyor.. */
  148. }
  149.  
  150. =====================================================================
  151.  
  152. Bu program, tek bir deger dondurmenin kolay oldugunu gosteriyor. Fakat,
  153. birden fazla deger dondurmek icin, baska metodlara gerek oldugunu
  154. hatirlamanizda fayda var. 
  155.  
  156. ana programda, iki tane tamsayi degiskeni tanimliyoruz, ve 8 kere islenen
  157. bir "for" dongusu baslatiyoruz. Dongudeki ilk satir, "y = squ(x);", yeni
  158. ve tuhaf gorunuslu bir satir. Onceki programlarda gordugumuz gibi, squ(x)
  159. kisimi, squ isimli fonksiyonu, x parametresi ile cagirmaktadir. Fonksiyona
  160. baktigimizda, bu gecen degiskenin orada 'in' isminde oldugunu, ve kare
  161. ismindeki yerel degiskene, gecirdigimiz degerin karesinin atandigini
  162. goruyoruz. Daha sonra, yeni "return" komutunu goruyoruz. Parantezler
  163. icindeki bu deger, fonksiyonun kendisine atanir, ve ana programa bu deger
  164. dondurulur. Yani, "squ(x)" fonksiyonu, x in karesine atanir, ve bu deger,
  165. ana programa atanir. Ornegin, x in degeri 4 ise, y nin degeri, "y=squ(x)"
  166. satirindan sonra 16 olacaktir.
  167.  
  168. Bir baska dusunme sekli de, "squ(x)" sozcugunu, "x" in karesi degerinde bir
  169. degisken olarak dusunmektir. Bu yeni degisken de, degiskenlerin
  170. kullanildigi herhangi bir yerde kullanilabilir. Baska bir degisken olarak
  171. gormeye bir ornek olarak bu programda ikinci bir dongu vardir. Burada,
  172. y degiskenine atamak yerine, printf'in icinde, bu fonksiyonu cagiriyoruz.
  173.  
  174. Bir fonksiyondan donecek degiskenin tipi, derleyiciye bildirilmelidir.
  175. Fakat, bizim yaptigimiz gibi sayet belirtmezsek, derleyici donecek degerin
  176. tam sayi (integer) olacagini kabul edecektir. Baska tiplerin tanimlanmasini
  177. ise, bundan sonraki programda gorecegiz..
  178.  
  179.  
  180. KAYAR NOKTA FONKSIYONLARI
  181.  
  182. KAYARKAR.C:
  183. ================================================================
  184.  
  185. float z;   /* Bu bir global degiskendir */
  186.  
  187. main()
  188. {
  189. int index;
  190. float x,y,sqr(),glsqr();
  191.  
  192.    for (index = 0;index <= 7;index++){
  193.       x = index;  /* int'i float yapalim  */
  194.       y = sqr(x); /* x'in karesini alalim..   */
  195.       printf("%d in karesi %10.4f dir.\n",index,y);
  196.    }
  197.  
  198.    for (index = 0; index <= 7;index++) {
  199.       z = index;
  200.       y = glsqr();
  201.       printf("%d in karesi %10.4f dir.\n",index,y);
  202.    }
  203. }
  204.  
  205. float sqr(deger)  /* float'in karesini al, float dondur. */
  206. float deger;
  207. {
  208. float karesi;
  209.  
  210.    karesi = deger * deger;
  211.    return(karesi);
  212. }
  213.  
  214. float glsqr()    /* float'in karesini al, float dondur. */
  215. {
  216.    return(z*z);
  217. }
  218. ================================================================
  219.  
  220. KAYARKAR.C isimli programa bir bakin. Ilk once daha sonra kullanacagimiz
  221. bir global degisken tanimlamak ile basliyor. Programin "main" kisiminda,
  222. bir tamsayi degiskeni tanimlaniyor. Bunun altinda, iki tani tamsayi
  223. degiskeni, iki tane de tuhaf gorunuslu tanimlamalar var. "sqr()" ve
  224. "glsqr()" isimli iki fonksiyon gibi gorunuyorlar, ve oyleler. Bu, C
  225. dilinde "int" yani tamsayi dan baska birsey dondurecek bir fonksiyonun
  226. (float mesela) resmi sekilde tanimlanmasidir. Bu derleyiciye, bu iki
  227. fonksiyondan bir deger donunce, bu degerin float olacagini bildiriyor. 
  228.  
  229. Simdi programin ortasinda yer alan "sqr" fonksiyonuna bir bakin. Burada
  230. fonksiyonun isminin basinda bir "float" sozcugu goreceksiniz. Bu
  231. derleyiciye herhangi bir yerden bu fonksiyon cagirilinca, donecek degerin
  232. float olacagini bildiriyor. Simdi bu fonksiyon, ana programdaki cagirma
  233. ile uyumludur. Bunun altinda, "float deger" satirini goruyorsunuz. Bu da,
  234. bu fonksiyona, cagiran tarafindan gecirilecek degerin, bir "float" yani
  235. kayar nokta olacagini bildirir. 
  236.  
  237. Bundan sonraki fonksiyon "glsqr" da, bir kayar nokta donduruyor, fakat o,
  238. input icin global bir degikeni (z degiskenini) kullaniyor. Ayrica, yeni
  239. bir degisken tanimlamadan, karesini almayi "return" komutunun icinde
  240. yapiyor. 
  241.  
  242. DEGISKENLERIN ALANI
  243.  
  244. ALAN.C:
  245. ================================================================
  246. int say;        /* Bu bir global degiskendir.  */
  247.  
  248. main()
  249. {
  250. register int index; /* Bu degisken sadece "main" icinde kullanilabilir */
  251.  
  252.    baslik_1();
  253.    baslik_2();
  254.    baslik_3();
  255.                       /* bu programin ana "for" dongusu  */
  256.    for (index = 8;index > 0;index--)
  257.    {
  258.       int birsey; /* Bu degisken sadece bu kume isaretleri arasinda tanimli */
  259.      
  260.       for (birsey = 0;birsey <= 6;birsey++)
  261.          printf("%d ",birsey);
  262.  
  263.       printf(" index simdi: %d oldu.\n",index);
  264.     }
  265. }
  266.  
  267. int sayac;      /* Bu degisken bu noktadan sonra kullanilabilir. */
  268.  
  269. baslik_1()
  270. {
  271. int index;        /* Bu degisken sadece baslik_1 icinde tanimli */
  272.  
  273.    index = 23;
  274.    printf("Baslik_1 deki degeri %d\n",index);
  275. }
  276.  
  277. baslik_2()
  278. {
  279. int say;    /* Bu degisken sadece baslik_2 icinde gecerli */
  280.             /* ayni isimli global degiskenin yerini alir.. */
  281.  
  282.    say = 53;
  283.    printf("Baslik_2 deki degeri %d\n",say);
  284.    sayac = 77;
  285. }
  286.  
  287. baslik_3()
  288. {
  289.    printf("Baslik_3 deki degeri ise %d\n",sayac);
  290. }
  291. ================================================================
  292.  
  293. Ilk tanimlanan degisken "say", butun fonksiyonlardan once tanimlandigi
  294. icin, herhangi biri tarafindan cagirilabilir, ve daima erisilebilir. Daha
  295. sonra, "sayac" isimli bir degisken tanimliyoruz. Bu da global bir
  296. degiskendir, fakat ana programdan sonra tanimlandigi icin, ana program
  297. tarafindan kullanilamaz. Global bir degisken, fonksiyonlarin disinda
  298. tanimlanan degiskenlere denir. Bu tip degiskenlere dissal degiskenler adi
  299. da verilebilir. 
  300.  
  301. Ana programa geri donerek, "index" isimli degiskenin tanimina bakalim. Su
  302. an icin "register" sozcugunu goz onune almayin. Bu degisken "otomatik" bir
  303. degiskendir, yani o fonksiyon cagirildiginda olusur, ve fonksiyondan
  304. cikinca kaybolur. Ana program baska fonksiyonlari cagirdiginda bile daima
  305. calisir oldugundan, burada pek manasi yoktur. Tanimlanan diger bir
  306. degisken de, "birsey" degiskenidir. Bu degisken, sadece "for" dongusunun
  307. icinde tanimlidir, ve baska bir yerden erisilemez. Herhangi bir kume
  308. dongusunun basina, degisken tanimlamalari konulabilir. Kumeden cikinca, bu
  309. degisken tanimsiz olacaktir. 
  310.  
  311. OTOMATIK DEGISKENLER HAKKINDA...
  312.  
  313. Baslik_1'e bir bakin. "index" isimli bir degisken kullaniyor. Bu
  314. degiskenin ana programdaki "index" ile arasinda, ikisinin de otomatik
  315. degisken olmasi disinda hicbir bag yoktur. Program, bu fonksiyonu
  316. islemezken, bu degisken yoktur bile. Baslik_1 cagirildiginda, bu degisken
  317. yaratilir, ve baslik_1 bitince de bu degisken silinir. Fakat bu, ana
  318. programdaki ayni isimli degiskenin degerini hic etkilemez, cunku ayri
  319. nesnelerdir.
  320.  
  321. Yani otomatik degiskenler, gerektiginde yaratilirlar, ve isleri bitince de
  322. silinirler. Hatirlamaniz gereken bir nokta da, bir fonksiyon birden fazla
  323. kere cagirildiginda, otomatik degiskenlerin eski degerleri saklanmaz, yeni
  324. bastan deger atanmalari gerekir. 
  325.  
  326. STATIK DEGISKENLER ?
  327.  
  328. Bir baska degisken tipi ise, statik degiskenlerdir. Degiskeni tanimlarken
  329. basina "static" sozcugunu koyarak, o degisken yada degiskenler,
  330. fonksiyonun tekrar tekrar cagirilmasinda, eski degerlerini tutarlar.
  331.  
  332. Ayni sozcugu bir global degiskenin onune koyarak, o degiskenin sadece o
  333. kutuk icindeki fonksiyonlara tanimli olmasini saglayabiliriz. Bundanda
  334. anlayacaginiz gibi, birkac parcadan olusan kutukler arasinda global
  335. degiskenlerin tanimlanmasi mumkundur. Bunu 14. konuda daha iyi gorecegiz.
  336.  
  337. AYNI ISMI TEKRAR KULLANMAK
  338.  
  339. baslik_2 ye bir bakin. Burada "say" isimli degiskenin tekrar
  340. tanimlandigini ve 53 degerini aldigini goruyoruz. Global olarak
  341. tanimlanmasina karsin, ayni isimde bir otomatik degisken tanimlamak
  342. mumkundur. Bu degisken tumuyle yeni bir degiskendir, ve global olarak,
  343. programin basinda tanimlanan "say" ile arasinda hicbir baglanti yoktur. Bu
  344. sayede kafanizda "acaba global isimlerle karisirmi" sorusu olmadan
  345. fonksiyon yazabilirsiniz.
  346.  
  347. REGISTER DEGISKENLERI NEDIR
  348.  
  349. Sozumu tutarak, register degiskenine donelim. Bir bilgisayar bilgiyi
  350. hafizada yada registerlerde tutabilir. Register sahasina erisim, hafizaya
  351. erisimden cok daha hizlidir, fakat programcinin kullanabilecegi az sayida
  352. register vardir. Bazi degiskenlerin program tarafindan cok kullanilacagini
  353. dusunuyorsaniz, o degiskeni "register" olarak tanimlayabilirsiniz.
  354. Bilgisayar ve derleyici tipinize gore, bir yada birkac degiskeni bu
  355. sekilde tanimlayabilirsiniz. Cogu derleyicilerin hic register degiskenleri
  356. yoktur, ve "register" sozcugunu goz onune almadan derleme yaparlar. 
  357.  
  358. Register degiskenleri, sadece tamsayi ve karakter tipi degiskenler ile
  359. kullanilabilir. Sectiginiz derleyiciye gore, unsigned, long yada short
  360. tipleride register olabilir. 
  361.  
  362. DEGISKENLERI NEREDE TANIMLAYALIM
  363.  
  364. Bir fonksiyona parametre olarak gecirilmis degiskenler varsa, bunlarin
  365. tanimi, fonksiyon isminden sonra, ve acik kume isaretinden once
  366. yapilmalidir. Fonksiyonda kullanilan diger degiskenler ise, fonksiyonun
  367. basinda, hemen acik kume isaretinden sonra tanimlanir. 
  368.  
  369. STANDART FONKSIYON KUTUPHANESI
  370.  
  371. Her derleyici, icinde bircok fonksiyon olan bir kutuphane ile birlikte
  372. gelir. Bunlar genellikle giris/cikis islemleri, karakter ve katar isleme,
  373. ve matemetiksel fonksiyonlari icerir. Bunlarin cogunu sonraki konularda
  374. gorecegiz. 
  375.  
  376. Bunun disinda, cogu derleyicinin, standart olmayan, ve kullandiginiz
  377. bilgisayarin ozelliklerini kullanan, ilave fonksiyonlari vardir. Ornegin,
  378. IBM-PC ve uyumlular icin, BIOS servislerini kullanan fonksiyonlar
  379. sayesinde, isletim sistemine komutlar vermeyi, yada ekrana direk yazmayi
  380. saglayan fonksiyonlar olabilir. 
  381.  
  382. RECURSION NEDIR ?
  383.  
  384. RECURS.C:
  385. ================================================================
  386.  
  387. main()
  388. {
  389. int index;
  390.  
  391.    index = 8;
  392.    geri_say(index);
  393. }
  394.  
  395. geri_say(rakam)
  396. int rakam;
  397. {
  398.    rakam--;
  399.    printf("rakam degeri %d dir.\n",rakam);
  400.    if (rakam > 0)
  401.       geri_say(rakam);
  402.    printf("Simdi rakam %d oldu..\n",rakam);
  403. }
  404.  
  405. ================================================================
  406.  
  407. Recursion, ilk karsilasildiginda cok korkutucu gorunen bir kavramdir.
  408. Fakat RECURS.C isimli programa bakarsaniz, recursion'un butun zorlugunu
  409. yenebiliriz. Aslinda fazla basit ve dolayisi ile aptal olan bu program,
  410. bize recursion'un kullanimini gostermesi bakimindan cok yararlidir. 
  411.  
  412. Recursion, kendini cagiran bir fonksiyondan baska birsey degildir. Yani,
  413. bitmek icin bir kontrol mekanizmasina ihtiyaci olan bir dongudur.
  414. Karsinizdaki programda "index" degiskeni 8 e atanir, ve "geri_say"
  415. fonksiyonunun parametresi olarak kullanilir. Bu fonksiyon da, bu
  416. degiskenin degerini teker teker azaltir, ve bize bu degeri gosterir. Sonra
  417. tekrar kendisini cagirir, degeri bir kez daha azalir, tekrar, tekrar..
  418. Sonunda deger sifira ulasir, ve dongu artik kendini cagirmaz. Bunun
  419. yerine, daha onceki cagirmada kaldigi yere geri doner, tekrar geri doner,
  420. en sonunda ana programa geri doner, ve program sona erer.
  421.  
  422.  
  423. NE OLDU ?
  424.  
  425. Fonksiyon kendisini cagirdiginda, butun degiskenlerini,ve cagirilan
  426. fonksiyonun islemesi bittiginde donmesi gereken yeri hafizaya sakladi.
  427. Bir dahaki sefere kendinin tekrar cagirdiginda, yine ayni seyi yapti, ta
  428. ki kendisini tekrar cagirmasi bitene kadar. Daha sonra tekrar bu
  429. bilgileri, ayni koyus sirasi ile geri okudu. 
  430.  
  431. Hatirlamaniz gereken nokta, recursion'un bir noktada bitmesi gerektigidir,
  432. sayet sonsuz bir donguye girerseniz, bilgisayarin hafizasi bitecek ve bir
  433. hata mesaji cikacaktir.
  434.  
  435. ODEVLER
  436.  
  437. 1. Daha once yazdigimiz Santigrad'dan Fahrenheit'a karsilik tablosundaki
  438. derece hesaplamasini bir fonksiyona geciriniz.
  439. 2. Ekrana isminizi 10 kere yazan bir program yaziniz. Yazma isini yapmak
  440. icin bir fonksiyon cagiriniz. Daha sonra bu fonksiyonu main() in basina
  441. alarak, derleyicinin bunu kabul edip etmedigini kontrol ediniz.
  442.